"""
页面对象模型的基类，包含所有页面共用的方法
"""
import os
import time
import logging
from datetime import datetime
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from tests.config.config import EXPLICIT_WAIT, SCREENSHOTS_DIR, BASE_URL


class BasePage:
    """所有页面对象的基类，包含通用方法"""

    def __init__(self, driver):
        """
        初始化基类
        
        Args:
            driver: WebDriver实例
        """
        self.driver = driver
        self.wait = WebDriverWait(self.driver, EXPLICIT_WAIT)
        
    def open(self, url=""):
        """
        打开指定URL
        
        Args:
            url: 要访问的URL，默认为空（使用BASE_URL）
        """
        full_url = f"{BASE_URL}/{url.lstrip('/')}" if url else BASE_URL
        logging.info(f"访问URL: {full_url}")
        self.driver.get(full_url)
        
    def find_element(self, locator):
        """
        查找单个元素
        
        Args:
            locator: 元素定位器，格式为(By.XXX, "value")
            
        Returns:
            找到的WebElement对象
        """
        try:
            return self.wait.until(EC.presence_of_element_located(locator))
        except TimeoutException:
            logging.error(f"查找元素超时: {locator}")
            self.take_screenshot(f"find_element_error_{locator[1]}")
            raise
            
    def find_elements(self, locator):
        """
        查找多个元素
        
        Args:
            locator: 元素定位器，格式为(By.XXX, "value")
            
        Returns:
            找到的WebElement对象列表
        """
        try:
            return self.wait.until(EC.presence_of_all_elements_located(locator))
        except TimeoutException:
            logging.error(f"查找多个元素超时: {locator}")
            self.take_screenshot(f"find_elements_error_{locator[1]}")
            return []
            
    def click(self, locator):
        """
        点击元素
        
        Args:
            locator: 元素定位器，格式为(By.XXX, "value")
        """
        try:
            element = self.wait.until(EC.element_to_be_clickable(locator))
            element.click()
            logging.info(f"点击元素: {locator}")
        except Exception as e:
            logging.error(f"点击元素失败: {locator}, 错误: {e}")
            self.take_screenshot(f"click_error_{locator[1]}")
            raise
            
    def input_text(self, locator, text):
        """
        在输入框中输入文本
        
        Args:
            locator: 元素定位器，格式为(By.XXX, "value")
            text: 要输入的文本
        """
        try:
            element = self.find_element(locator)
            element.clear()
            element.send_keys(text)
            logging.info(f"在元素 {locator} 中输入文本: {text}")
        except Exception as e:
            logging.error(f"输入文本失败: {locator}, 文本: {text}, 错误: {e}")
            self.take_screenshot(f"input_error_{locator[1]}")
            raise
            
    def get_text(self, locator):
        """
        获取元素文本
        
        Args:
            locator: 元素定位器，格式为(By.XXX, "value")
            
        Returns:
            元素的文本内容
        """
        try:
            element = self.find_element(locator)
            text = element.text
            logging.info(f"获取元素 {locator} 的文本: {text}")
            return text
        except Exception as e:
            logging.error(f"获取文本失败: {locator}, 错误: {e}")
            self.take_screenshot(f"get_text_error_{locator[1]}")
            raise
            
    def is_element_present(self, locator):
        """
        检查元素是否存在
        
        Args:
            locator: 元素定位器，格式为(By.XXX, "value")
            
        Returns:
            布尔值，表示元素是否存在
        """
        try:
            self.find_element(locator)
            return True
        except (TimeoutException, NoSuchElementException):
            return False
            
    def is_current_url_contains(self, text):
        """
        检查当前URL是否包含指定文本
        
        Args:
            text: 要检查的文本
            
        Returns:
            布尔值，表示URL是否包含指定文本
        """
        current_url = self.driver.current_url
        logging.info(f"检查当前URL '{current_url}' 是否包含 '{text}'")
        return text in current_url
            
    def take_screenshot(self, name=None):
        """
        截取当前页面的屏幕截图
        
        Args:
            name: 截图文件名，默认为当前时间戳
        """
        if name is None:
            name = f"screenshot_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
        
        if not os.path.exists(SCREENSHOTS_DIR):
            os.makedirs(SCREENSHOTS_DIR)
            
        file_path = os.path.join(SCREENSHOTS_DIR, f"{name}.png")
        self.driver.save_screenshot(file_path)
        logging.info(f"截图已保存: {file_path}")
        return file_path
        
    def wait_for_page_load(self, timeout=None):
        """
        等待页面加载完成
        
        Args:
            timeout: 超时时间（秒），如果为None则使用默认超时时间
        """
        if timeout is None:
            timeout = EXPLICIT_WAIT
            
        try:
            self.wait.until(lambda d: d.execute_script("return document.readyState") == "complete")
            logging.info("页面加载完成")
        except TimeoutException:
            logging.error("等待页面加载超时")
            self.take_screenshot("page_load_timeout")
            raise
            
    def scroll_to_element(self, locator):
        """
        滚动到指定元素
        
        Args:
            locator: 元素定位器，格式为(By.XXX, "value")
        """
        try:
            element = self.find_element(locator)
            self.driver.execute_script("arguments[0].scrollIntoView(true);", element)
            time.sleep(0.5)  # 等待滚动完成
            logging.info(f"滚动到元素: {locator}")
        except Exception as e:
            logging.error(f"滚动到元素失败: {locator}, 错误: {e}")
            raise 